package comm;

import comm.forms.FunAnalysisForm;
import comm.receive.ReceiveServerData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import java.awt.*;
import java.awt.event.*;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.util.Objects;
import java.util.Vector;

public class ClientMain extends JFrame {
    private static final Logger logger = LoggerFactory.getLogger(ClientMain.class);

    public static void main(String[] args) {
        new ClientMain();
    }


    final JFrame jFrame = new JFrame("订阅工具登陆");

    JTable jTable;
    //过滤设备号list
    Vector<String> numbers = new Vector<>();
    JList<String> jbnumbers = new JList<>(numbers);

    //定义客户端
    Socket client;

    //数据处理线程，用于解析接收到的数据
    //Thread thread;

    //过滤消息ID，list
    Vector<String> messages = new Vector<>();
    JList<String> jlmessageids = new JList<>(messages);

    //服务端IP和端口号
    String Ip;
    Integer Port;

    //订阅一个字节介入，往服务端写入
    final BufferedWriter[] bufferedWriter = new BufferedWriter[1];

    Thread thread;


    public ClientMain() {


        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        int windowsWidth = 400;
        int windowsHeight = 330;
        jFrame.setBounds((width - windowsWidth) / 2,
                (height - windowsHeight) / 2, windowsWidth, windowsHeight);
        jFrame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);


        //IP
        JLabel jLabelIP = new JLabel("tcp连接状态：未连接");
        jLabelIP.setText("订阅的服务IP地址：");
        jLabelIP.setBounds(60, 40, 200, 30);
        //输入框
        final JTextField jTextFieldIP = new JTextField(20);
        jTextFieldIP.setText("192.168.2.112");
        jTextFieldIP.setBounds(180, 45, 100, 20);

        //端口
        JLabel jLabelPort = new JLabel();
        jLabelPort.setText("订阅服务的Port：");
        jLabelPort.setBounds(60, 80, 120, 30);
        //输入框
        final JTextField jTextFieldPort = new JTextField(20);
        jTextFieldPort.setText("11400");
        jTextFieldPort.setBounds(180, 85, 100, 20);

        //连接
        JButton jLogButton = new JButton("连接");
        jLogButton.setBounds(50, 150, 100, 30);
        jLogButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //连接
                Connection(jTextFieldIP, jTextFieldPort);

            }
        });
        //关闭
        JButton jColesButton = new JButton("关闭");
        jColesButton.setBounds(180, 150, 100, 30);
        jColesButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });

        JPanel jPanel = new JPanel();

        jFrame.add(jLabelIP);
        jFrame.add(jTextFieldIP);
        jFrame.add(jLabelPort);
        jFrame.add(jTextFieldPort);
        jFrame.add(jLogButton);
        jFrame.add(jColesButton);

        jFrame.add(jPanel);
        jFrame.setVisible(true);


        logger.info("客户端启动成功");
    }


    //连接服务器
    public void Connection(JTextField jTextFieldIP, JTextField jTextFieldPort) {
        try {
            Ip = jTextFieldIP.getText();
            Port = Integer.parseInt(jTextFieldPort.getText());
//                    String ip = "127.0.0.1";
//                    int port = 8001;
            logger.info("连接服务器：" + jTextFieldIP.getText() + "端口：" + jTextFieldPort.getText());
            //客户端请求主机IP和Port
            client = new Socket(jTextFieldIP.getText(), Integer.parseInt(jTextFieldPort.getText()));

            if (client.isConnected()) {
                //连接上服务端之后，默认发送一条数据，防止多个客户端连接到服务端后，不发送任何数据，服务端阻塞
                bufferedWriter[0] = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));
                bufferedWriter[0].write("connection\n");
                bufferedWriter[0].flush();
                //创建二级窗体
                CreateJFrame();
            }
        } catch (IOException exception) {
            JOptionPane.showMessageDialog(null,
                    "连接失败，请确保ip和端口通道是否通畅！！！！！！错误提示：" + exception,
                    "提示", JOptionPane.ERROR_MESSAGE);
        }
    }


    //创建子界面
    public void CreateJFrame() {

        jFrame.setVisible(false);
        JFrame jFrameChil = new JFrame("订阅工具");
        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        int windowsWidth = 1200;
        int windowsHeight = 600;
//        frame.setSize(250, 350);
        jFrameChil.setBounds((width - windowsWidth) / 2,
                (height - windowsHeight) / 2, windowsWidth, windowsHeight);
        jFrameChil.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                try {
                    if (client.isConnected())
                        client.close();
                    System.exit(0);
                } catch (Exception ex) {
                    ex.toString();
                }
            }
        });

        //菜单栏
        JMenuBar jMenuBar = CreateJMenuBar();
        //过滤设备号容器
        JList<String> jList = CreateJlist();
        jList.setBounds(15, 170, 90, 340);
        jList.setBackground(Color.LIGHT_GRAY);


        //过滤设备号容器
        JPanel jPanel = new JPanel();
        jPanel.setBorder(BorderFactory.createTitledBorder("过滤设备号"));
        jPanel.setBounds(10, 150, 100, 360);
        jPanel.add(jList, BorderLayout.CENTER);

        //过滤消息ID容器
        JList<String> jListMessage = CreateMessageidList();
        jListMessage.setBounds(100, 170, 90, 340);
//        jListMessage.setBackground(Color.LIGHT_GRAY);
        //过滤设备号容器
        JPanel jPanelMessage = new JPanel();
        jPanelMessage.setBorder(BorderFactory.createTitledBorder("过滤消息ID"));
        jPanelMessage.setBounds(120, 150, 100, 360);
        jPanelMessage.add(jListMessage, BorderLayout.CENTER);

        //订阅按钮
        final JButton jbtSubscribe = new JButton("订阅");
        jbtSubscribe.setBounds(10, 10, 200, 30);

        //取消订阅按钮
        JButton jBtEmpty = new JButton("取消订阅");
        jBtEmpty.setBounds(10, 50, 200, 30);

        //清空列表按钮
        JButton jBtCancel = new JButton("清空列表");
        jBtCancel.setBounds(10, 90, 200, 30);

        String[] headers = {"时间", "设备号", "消息ID", "方向", "数据", "本地", "远程"};
        Object[][] cellData = null;

        TableModel model = new DefaultTableModel(cellData, headers) {
            //设置不能编辑table数据 内容
            public boolean isCellEditable(int row, int column) {
                return false;
            }
        };

        jTable = new JTable(model);


        final JScrollPane jScrollPane = new JScrollPane(jTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        jScrollPane.setBounds(220, 10, 970, 500);

        JPanel panel = new JPanel();
        panel.setBounds(0, 0, 200, 530);
//        panel.setBackground(Color.gray);
        panel.setLayout(null);   //设置panel面板布局为空布局

        //可以根据标题排序
        jTable.setRowSorter(new TableRowSorter<TableModel>(jTable.getModel()));

        jFrameChil.setJMenuBar(jMenuBar);
        jFrameChil.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jTable.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getClickCount() == 2) {
                    DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();
                    Object valueAt = tableModel.getValueAt(jTable.getSelectedRow(), 4);
                    FunAnalysisForm from = new FunAnalysisForm();
                    from.FunAnalysisFormView(valueAt.toString());
                }
            }
        });

        //订阅按钮，点击事件
        jbtSubscribe.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                try {

                    if (client.isConnected() && !client.isClosed() && !client.isOutputShutdown()) {
                        //发送给服务端
                        //BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));//从控制台获取信息
                        bufferedWriter[0] = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));

                        StringBuilder senddev = new StringBuilder();
                        for (int i = 0; i < jbnumbers.getModel().getSize(); i++) {
                            senddev.append(jbnumbers.getModel().getElementAt(i)).append(",");
                        }
                        //判断将选中的设备号发送给服务端
                        if (!Objects.equals(senddev.toString(), "")) {
                            bufferedWriter[0].write(senddev.toString());
                            bufferedWriter[0].write("\n");//表示一条信息结束了，服务端通过
                            bufferedWriter[0].flush();

                            ReceiveServerData data = new ReceiveServerData(jTable, client, jbtSubscribe, jListMessage);
                            if (thread != null) {
                                try {
                                    thread.destroy();
                                    thread.interrupt();
                                    //client.close();
                                } catch (Exception destroyE) {
                                    destroyE.printStackTrace();
                                }
                            }
                            thread = new Thread(data);
                            thread.start();
                        }
                    } else {
                        //发送给服务端
                        //BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));//从控制台获取信息
                        client = new Socket(Ip, Port);
                        logger.info("重连IP：" + Ip + ",prot：" + Port);
                        if (client.isConnected() && !client.isOutputShutdown())
                        {
                            bufferedWriter[0] = new BufferedWriter(new OutputStreamWriter(client.getOutputStream()));

                            StringBuilder senddev1 = new StringBuilder();
                            for (int i = 0; i < jbnumbers.getModel().getSize(); i++) {
                                senddev1.append(jbnumbers.getModel().getElementAt(i)).append(",");
                            }
                            //判断将选中的设备号发送给服务端
                            if (!Objects.equals(senddev1.toString(), "")) {
                                bufferedWriter[0].write(senddev1.toString());
                                bufferedWriter[0].write("\n");//表示一条信息结束了，服务端通过
                                bufferedWriter[0].flush();

                                ReceiveServerData data = new ReceiveServerData(jTable, client, jbtSubscribe, jListMessage);

                                if (thread != null) {
                                    try {
                                        thread.interrupt();
                                    } catch (Exception destroyE) {
                                        destroyE.printStackTrace();
                                    }
                                }
                                thread = new Thread(data);
                                thread.start();
                            }
                        }
                    }
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(null,
                            "与服务端连接断开，点击订阅代表重连！！！！！！错误提示：" + ex,
                            "提示", JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        //取消订阅按钮
        jBtEmpty.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {

                try {


                    //thread.stop();
                    client.getOutputStream().close();
                    client.getOutputStream().flush();
                    client.close();
                } catch (IOException exception) {
                    exception.printStackTrace();
                }
            }
        });

        //清空列表按钮
        jBtCancel.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
//              清空table列表方法二
                DefaultTableModel tableModel = (DefaultTableModel) jTable.getModel();
                tableModel.setRowCount(0);
            }
        });

        //获取选中jlist行
        jListMessage.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                int index = jListMessage.getSelectedIndex();
                jListMessage.remove(index);
            }
        });

        panel.add(jList);
        panel.add(jbtSubscribe);
        panel.add(jBtEmpty);
        panel.add(jBtCancel);
        panel.add(jPanel);
        panel.add(jPanelMessage);
        panel.add(jScrollPane);
        jFrameChil.add(panel);

        jFrameChil.setVisible(true);
    }

    //设置菜单栏
    public JMenuBar CreateJMenuBar() {
        JMenuBar bar = new JMenuBar();
        JMenu file = new JMenu("菜单");
        JMenuItem jIcreatenumbers = new JMenuItem("添加设备号");
        JMenuItem jIcreateMessageId = new JMenuItem("添加消息ID");
        JMenuItem jIdeletenumbers = new JMenuItem("删除设备号");
        JMenuItem jIdeleteMessageId = new JMenuItem("删除消息ID");

        jIcreatenumbers.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                //消息ID
                CreateDeviceNum(0);
            }
        });
        jIcreateMessageId.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //设备号
                CreateDeviceNum(1);
            }
        });
        jIdeletenumbers.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //删除设备号
                deleteFun(0);
            }
        });
        jIdeleteMessageId.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //删除消息ID
                deleteFun(1);
            }
        });


        file.add(jIcreatenumbers);
        file.add(jIcreateMessageId);
        file.add(jIdeletenumbers);
        file.add(jIdeleteMessageId);
        bar.add(file);
        return bar;
    }


    //删除设备号。消息ID
    public void deleteFun(int index) {
        final JFrame jFrameChil = new JFrame();
        if (index != 0) {
            jFrameChil.setTitle("删除消息ID");
        } else {
            jFrameChil.setTitle("删除订阅的设备号");
        }
        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        int windowsWidth = 400;
        int windowsHeight = 100;
        jFrameChil.setBounds((width - windowsWidth) / 2, (height - windowsHeight) / 2, windowsWidth, windowsHeight);


        final JLabel lbDeviceNum = new JLabel();
        if (index != 0) {
            lbDeviceNum.setText("消息ID:");
        } else {
            lbDeviceNum.setText("设备号:");
        }
        lbDeviceNum.setSize(50, 20);
        lbDeviceNum.setLocation(40, 25);


        final JTextField jfDeviceNum = new JTextField("", 1);
        jfDeviceNum.setSize(100, 20);
        jfDeviceNum.setLocation(110, 25);

        //确定按钮
        final JButton jButton = new JButton("确定");
        jButton.setBounds(250, 25, 80, 20);
        jButton.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String DeviceNum = jfDeviceNum.getText();
                if (index != 0) {
                    messages.remove(DeviceNum);
                } else {
                    numbers.remove(DeviceNum);
                }
                jbnumbers.updateUI();
                jlmessageids.updateUI();
                jFrameChil.dispose();
            }
        });


        JPanel jpanel = new JPanel();
        jFrameChil.add(lbDeviceNum);
        jFrameChil.add(jfDeviceNum);
        jFrameChil.add(jButton);
//        jpanel.updateUI();
        jFrameChil.add(jpanel);
        jFrameChil.setVisible(true);
    }


    //过滤设备号展示
    public JList<String> CreateJlist() {
        jbnumbers.setListData(numbers);
        jbnumbers.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        return jbnumbers;
    }

    //过滤消息id号展示
    public JList<String> CreateMessageidList() {
        jlmessageids.setListData(messages);
        jlmessageids.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        return jlmessageids;
    }

    //添加设备号界面
    public void CreateDeviceNum(final int DistinguishID) {
        final JFrame jFrameChil = new JFrame();
        if (DistinguishID != 0) {
            jFrameChil.setTitle("添加消息ID");
        } else {
            jFrameChil.setTitle("添加订阅的设备号");
        }
        int width = Toolkit.getDefaultToolkit().getScreenSize().width;
        int height = Toolkit.getDefaultToolkit().getScreenSize().height;
        int windowsWidth = 400;
        int windowsHeight = 100;
        jFrameChil.setBounds((width - windowsWidth) / 2, (height - windowsHeight) / 2, windowsWidth, windowsHeight);

        //设备号
        final JLabel lbDeviceNum = new JLabel();
        if (DistinguishID != 0) {
            lbDeviceNum.setText("消息ID:");
        } else {
            lbDeviceNum.setText("设备号:");
        }
        lbDeviceNum.setSize(50, 20);
        lbDeviceNum.setLocation(40, 25);

        //设备号输入框
        final JTextField jfDeviceNum = new JTextField("", 1);
        jfDeviceNum.setSize(100, 20);
        jfDeviceNum.setLocation(110, 25);

        //确定按钮
        final JButton jButton = new JButton("确定");
        jButton.setBounds(250, 25, 80, 20);
        jButton.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String DeviceNum = jfDeviceNum.getText();
                if (DistinguishID != 0) {
                    messages.add(DeviceNum);
                } else {
                    numbers.add(DeviceNum);
                }
                jbnumbers.updateUI();
                jlmessageids.updateUI();
                jFrameChil.dispose();
            }
        });


        JPanel jpanel = new JPanel();
        jFrameChil.add(lbDeviceNum);
        jFrameChil.add(jfDeviceNum);
        jFrameChil.add(jButton);
//        jpanel.updateUI(); 
        jFrameChil.add(jpanel);
        jFrameChil.setVisible(true);
    }
}